package com.code.demo;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

/**
 * 验证码工具类
 */
public class CaptcahCode {

    public static void main (String[] args) {
        drawImage(null);
    }

    /**
     * 生成验证码的方法
     * @param response
     * @return
     */
    public static String drawImage (HttpServletResponse response) {
        // 定义 StringBuilder 类
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < 4; i++) {
            builder.append(randomChar());
        }
        String code = builder.toString();
        // 定义图片宽高
        int width = 120;
        int height = 25;
        // 建立 bufferImage 对象，制定图片的长宽以及色彩
        BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
        // 获取 Graphics2D 画笔
        Graphics2D g = bi.createGraphics();
        // 设置文字大小和字体
        Font font = new Font("微软雅黑", Font.PLAIN, 20);
        g.setFont(font);
        g.setColor(new Color(0, 0, 0));
        g.setBackground(new Color(226, 226, 240));
        // 绘制矩形的区域
        g.clearRect(0, 0, width, height);
        // 绘制形状
        FontRenderContext context = g.getFontRenderContext();
        Rectangle2D bounds = font.getStringBounds(code, context);
        // 计算文字的坐标和间距
        double x = (width - bounds.getWidth()) / 2;
        double y = (height - bounds.getHeight()) / 2;
        double ascent = bounds.getY();
        double baseY = y - ascent;
        g.drawString(code, (int)x, (int)baseY);
        // 结束绘制
        g.dispose();
        // 图片保存输出
        try {
            ImageIO.write(bi, "jpg", response.getOutputStream());
            // 刷新响应流
            response.flushBuffer();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return code;
    }

    /**
     * 绘制算数表达式的验证码
     * @param response
     * @return
     */
    public static String drawImageVerificate (HttpServletResponse response) {
        // 定义验证码的宽度和高度
        int width = 100, height = 25;
        // 在内存中创建图片
        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 创建图片上下文
        Graphics2D g = bufferedImage.createGraphics();
        // 产生随机对象，用于算数表达式
        Random random = new Random();
        // 设置背景颜色
        g.setBackground(getRandomColor(240, 250));
        // 设置字体
        g.setFont(new Font("微软雅黑", Font.PLAIN, 20));
        // 开始绘制
        g.fillRect(0, 0, width, height);

        // 干扰线绘制
        g.setColor(getRandomColor(180, 230));
        for (int i = 0; i < 100; i++) {
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int x1 = random.nextInt(60);
            int y1 = random.nextInt(60);
            g.drawLine(x, y, x1, y1);
        }
        // 开始对算数验证码表达式拼接
        int num1 = (int)(Math.random()*10 + 1);
        int num2 = (int)(Math.random()*10 + 1);
        int symbolNum = random.nextInt(3); // 0, 1, 2
        String symbolStr = "";
        int result = 0;
        switch (symbolNum) {
            case 0: symbolStr = "+"; result = num1 + num2; break;
            case 1: symbolStr = "-"; result = num1 - num2; break;
            case 2: symbolStr = "x"; result = num1 * num2; break;
        }
        // 拼接算数表达式，用于图片显示文字
        String calc = num1 + " " + symbolStr + " " + num2 + " = ?";
        //设置随机颜色
        g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));
        //绘制表达式
        g.drawString(calc, 5, 25);
        // 结束绘制
        g.dispose();
        try {
            ImageIO.write(bufferedImage, "JPEG", response.getOutputStream());
            return String.valueOf(result);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 此方法用于产生随机字母和数字
     * @return
     */
    private static char randomChar () {
        // 定义验证码需要的字母和数字
        String string = "QWERTYUIOPASDFGHJKLZXCVBNM1234567890";
        // 生成随机对象
        Random random = new Random();
        // 返回一个随机字符
        return string.charAt(random.nextInt(string.length()));
    }

    /**
     * 返回随机颜色
     * @param fc
     * @param bc
     * @return
     */
    public static Color getRandomColor (int fc, int bc) {
        Random random = new Random();
        if (fc > 255) fc = 255;
        if (bc > 255) bc = 255;
        int r = fc + random.nextInt(bc - fc);
        int g = fc + random.nextInt(bc - fc);
        int b = fc + random.nextInt(bc - fc);
        return new Color(r, g, b);
    }

}
